#include "evolutionelement.h"

EvolutionElement::EvolutionElement(unsigned int& amountOfFormulasToCreate, unsigned int& sizeOfNewCreatedFormulas, Input& myInput)
    : inputIterator(myInput.getNewIterator()) {
    assert(amountOfFormulasToCreate>1);
    amountOfFormulas=amountOfFormulasToCreate;
    formulas=new Formula*[amountOfFormulasToCreate];
    initialFormulaLength=sizeOfNewCreatedFormulas;
    for (unsigned int i=amountOfFormulasToCreate; i--;)
        formulas[i]=FormulaFactory::createNewFormula(sizeOfNewCreatedFormulas,false);
    evaluate();
    sort();
}

EvolutionElement::~EvolutionElement() {
    for (unsigned int i=amountOfFormulas; i--;)
        delete formulas[i];
    delete [] formulas;
    delete &inputIterator;
}

void EvolutionElement::run(const unsigned int& amountOfRuns) {
    for(unsigned int r=amountOfRuns+1; --r;) {
        mutate();
        evaluate();
        sort();
    }
}

bool operator<(EvolutionElement& e1, EvolutionElement& e2) {
    if(e1.getBestFitnessScore() == e2.getBestFitnessScore())
        return e1.getFormulas()[0]->getSize() < e2.getFormulas()[0]->getSize();
    return e1.getBestFitnessScore() < e2.getBestFitnessScore();
}

bool operator>(EvolutionElement& e1, EvolutionElement& e2) {
    if (e1.getBestFitnessScore() == e2.getBestFitnessScore())
        return e1.getFormulas()[0]->getSize() > e2.getFormulas()[0]->getSize();
    return e1.getBestFitnessScore() > e2.getBestFitnessScore();
}

const double& EvolutionElement::getBestFitnessScore() {
    return formulas[0]->getFitness();
}
